package com.envoy.testsuite.mvc;

import java.awt.Component;
import java.awt.event.ActionListener;
import java.util.EnumMap;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class DummyDeviceManagerView extends JFrame implements View {

  /**
   * ID.
   */
  private static final long serialVersionUID = -2877079561873327745L;
  private JPanel contentPane;
  private JTextField idInput;
  private JTextField nameInput;
  private JTextField latitudeInput;
  private JTextField longitudeInput;
  private JTextField accuracyInput;
  private JTextField dateInput;
  private JButton btnCreateDevice, btnSendMessage;
  private JTextField destIdInput;
  private JTextArea messageInput;

  /**
   * Create the frame.
   */
  public DummyDeviceManagerView() {
    setTitle("Envoy Dummy Device Manager");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 526, 439);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JLabel lblDeviceCreation = new JLabel("Device Creation");
    lblDeviceCreation.setBounds(10, 11, 106, 14);
    contentPane.add(lblDeviceCreation);

    idInput = new JTextField();
    idInput.setBounds(10, 36, 106, 20);
    contentPane.add(idInput);
    idInput.setColumns(10);

    nameInput = new JTextField();
    nameInput.setBounds(10, 67, 106, 20);
    contentPane.add(nameInput);
    nameInput.setColumns(10);

    latitudeInput = new JTextField();
    latitudeInput.setBounds(10, 98, 33, 20);
    contentPane.add(latitudeInput);
    latitudeInput.setColumns(10);

    longitudeInput = new JTextField();
    longitudeInput.setColumns(10);
    longitudeInput.setBounds(53, 98, 31, 20);
    contentPane.add(longitudeInput);

    accuracyInput = new JTextField();
    accuracyInput.setBounds(94, 98, 22, 20);
    contentPane.add(accuracyInput);
    accuracyInput.setColumns(10);

    dateInput = new JTextField();
    dateInput.setBounds(10, 126, 106, 20);
    contentPane.add(dateInput);
    dateInput.setColumns(10);

    btnCreateDevice = new JButton("Create Device");
    btnCreateDevice.setBounds(10, 157, 106, 23);
    contentPane.add(btnCreateDevice);

    destIdInput = new JTextField();
    destIdInput.setBounds(10, 191, 106, 20);
    contentPane.add(destIdInput);
    destIdInput.setColumns(10);

    messageInput = new JTextArea();
    messageInput.setBounds(10, 222, 106, 82);
    contentPane.add(messageInput);

    JLabel lblDeviceId = new JLabel("Device ID");
    lblDeviceId.setBounds(126, 39, 125, 14);
    contentPane.add(lblDeviceId);

    JLabel lblUsername = new JLabel("Username");
    lblUsername.setBounds(126, 70, 69, 14);
    contentPane.add(lblUsername);

    JLabel lblGps = new JLabel("GPS");
    lblGps.setBounds(126, 101, 46, 14);
    contentPane.add(lblGps);

    JLabel lblDate = new JLabel("Date");
    lblDate.setBounds(126, 129, 46, 14);
    contentPane.add(lblDate);

    JLabel lblDestinationId = new JLabel("Destination ID");
    lblDestinationId.setBounds(126, 194, 93, 14);
    contentPane.add(lblDestinationId);

    JLabel lblMessage = new JLabel("Message");
    lblMessage.setBounds(126, 227, 93, 14);
    contentPane.add(lblMessage);

    btnSendMessage = new JButton("Send Message");
    btnSendMessage.setBounds(10, 315, 106, 23);
    contentPane.add(btnSendMessage);
  }

  /**
   * Displays the view.
   */
  @Override
  public final void run() {
    setVisible(true);
  }

  /**
   * Adds the button listeners to the buttons.
   * @param listeners the listeners to add.
   */
  @Override
  public final void attachListeners(final ActionListener[] listeners) {
    btnCreateDevice.addActionListener(listeners[0]);
    btnSendMessage.addActionListener(listeners[0]);
  }

  /**
   * Returns a list of parameters based on the given operation type.
   * @param operationType the type of operation the data is needed for.
   * @return the list of parameters requested.
   */
  @Override
  public final EnumMap<Parameter, String> getParameters(
      final OperationType operationType) {
    EnumMap<Parameter, String> parameters = new EnumMap<Parameter, String>(
        Parameter.class);
    switch (operationType) {
      case createNewDevice:
        parameters.put(Parameter.DeviceId, idInput.getText());
        parameters.put(Parameter.Name, nameInput.getText());
        parameters.put(Parameter.Latitude, latitudeInput.getText());
        parameters.put(Parameter.Longitude, longitudeInput.getText());
        parameters.put(Parameter.Accuracy, accuracyInput.getText());
        parameters.put(Parameter.GPSDate, dateInput.getText());
        break;
      case sendMessage:
        parameters.put(Parameter.DeviceId, idInput.getText());
        parameters.put(Parameter.DestinationId, destIdInput.getText());
        parameters.put(Parameter.MessageContent, messageInput.getText());
        parameters.put(Parameter.Latitude, latitudeInput.getText());
        parameters.put(Parameter.Longitude, longitudeInput.getText());
        parameters.put(Parameter.Accuracy, accuracyInput.getText());
        parameters.put(Parameter.GPSDate, dateInput.getText());
        break;
      default:
        System.out.println("Invalid type!");
        break;
    }
    return parameters;
  }

  /**
   * Updates the view with information from the model.
   * @param updateData the data required to update the view.
   * @return the result of the update.
   */
  @Override
  public final int update(
      final ModelTransferObject<ViewKey, UpdateType> updateData) {
    int result = 0;
    UpdateType updateType = updateData.getDataType();
    switch(updateType) {
      case connectionProblem:
        setInputEnabled(false);
        result = JOptionPane.showConfirmDialog(contentPane,
            "Attempt to reconnect?", "Connection error!",
            JOptionPane.OK_CANCEL_OPTION);
        break;
      case allIsWell:
        setInputEnabled(true);
        break;
      case deviceCreation:
        String messageString;
        String operationSuccess = updateData.getValue(ViewKey.operationSuccess);
        if (operationSuccess.equals("true")) {
          messageString = "Device created!";
        } else {
          messageString = "Device not created! :(";
        }
        JOptionPane.showMessageDialog(contentPane, messageString);
      default:
        break;
    }
    return result;
  }

  /**
   * Disables/enables all inputs.
   * @param enabled whether or not the inputs are enabled.
   */
  private void setInputEnabled(final boolean enabled) {
    /*idInput.setEnabled(enabled);
    nameInput.setEnabled(enabled);
    latitudeInput.setEnabled(enabled);
    longitudeInput.setEnabled(enabled);
    accuracyInput.setEnabled(enabled);
    dateInput.setEnabled(enabled);
    messageInput.setEnabled(enabled);
    destIdInput.setEnabled(enabled);
    btnCreateDevice.setEnabled(enabled);
    btnSendMessage.setEnabled(enabled);*/
    for (Component component : contentPane.getComponents()) {
      component.setEnabled(enabled);
    }
  }
}
